
var http = require('http');
var common = require('./common.js');
var path = require('path');
var fs = require('fs');
var spawn = require('child_process').spawn;

var listen_ip = '0.0.0.0';
var listen_port = 8124;
var keepalive = 1000;
var agent_index = -1;
var process_index = 0;

process.setMaxListeners(0);

var args_methods = {
    'master_addr' : function (v) {
        common.setMasterAddr(v);
    },
    'listen_port' : function (v) {
        listen_port = v;
    },
    'keepalive' : function (v) {
        keepalive = v;
    },
};

var processArray = [];

function startProcess(exec, args) {
    var processIndex = 0;
    for(processIndex=0; processArray.length; processIndex++) {
        if(processArray[processIndex]==null) break;
    }
    args.push('process_index='+processIndex);
    processArray[processIndex] = {};
    var pi = processArray[processIndex];
    pi.index = processIndex;
    pi.exec = exec;
    pi.args = args;
    pi.proc = spawn(process.argv[0], args);
    pi.proc.on('exit', function (code) {
        common.rlog(processIndex+' exited '+code)
        processArray[processIndex] = null;
    });
    pi.proc.stdout.on('data', function (data) {
//        console.log(String(data));
    });
    pi.proc.stderr.on('data', function (data) {
//        console.log(String(data));
    });
    return processIndex;
}

function stopProcess(index)
{
    if(index>=processArray.length) return false;
    if(processArray[index]==null) return false;
    processArray[index].proc.kill(9);
}

function listProcess()
{
    var ret = '';
    ret += '{';
    var first = true;
    for(var i=0; i<processArray.length; i++) {
        var pi = processArray[i];
        if(pi==null) continue;
        if(!first) ret += ', ';
        first = false;

        ret += '"' + i + '" : {';
        ret += '"index" : "' + i + '"';
        ret += ', "exec" : "' + encodeURIComponent(pi.exec) + '"';
        ret += ', "args" : "' + encodeURIComponent(String(pi.args)) + '"';
        ret += ', "pid" : "' + pi.proc.pid + '"';
        ret += '}';
    }
    ret += '}';
    return ret;
}

var http_methods = {
    'ping' : function (arg, req, res) {
        agent_index = arg;
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('pong');
    },
    'exit' : function (arg, req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('exit');
        process.exit(0);
    },
    'filesync' : function (arg, req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('not implement');
    },
    'runcase' : function (arg, req, res) {
        var a = arg.split('&');
        var params = {};
        params['master_addr'] = common.getMasterAddr();
        params['agent_index'] = agent_index;
        params['process_index'] = process_index++;
        params['case'] = 'undefined';
        for(var i in a) {
            var loc = a[i].indexOf('=');
            if(loc>0) {
                var name = a[i].substring(0, loc);
                var value = a[i].substring(loc+1);
                params[name] = value;
            } else {
                params[a[i]] = '';
            }
        }

        var casefile = 'cases/case_' + params['case'] + '.js';
        if(!path.existsSync(casefile)) {
            res.writeHead(500, { 'Content-Type': 'text/plain' });
            res.end(casefile + ' not found.');
            return;
        }

        var args = [];
        args.push('run_case.js')
        for(var i in params) {
            if(params[i]=='') {
                args.push(params[i]);
            } else {
                args.push(i + '=' + params[i]);
            }
        }

        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('done');

        startProcess(process.argv[0], args);
    },
    'stopcase' : function (arg, req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('not implement');
    },
    'listcase' : function (arg, req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(listProcess());
    },
};

common.parseArgs();
common.processArgs(args_methods);

if(listen_port==0) {
    listen_port = common.randomPort();
}

var httpd = http.createServer(function (req, res) {
    common.processHttpRequest(req, res, http_methods, false);
});

httpd.listen(listen_port, listen_ip);

console.log('webtest-agent started at ' + listen_ip + ':' + listen_port);

setInterval(function() {
    common.getUrlData('http://' + common.getMasterAddr() + '/api.register?' + listen_port, null, null);
}, keepalive);

if(!path.existsSync('log')) {
    fs.mkdirSync('log');
}
